﻿using System;
using System.Collections.Specialized;
using System.Windows.Forms;

namespace nhCommon
{
    /// <summary>
    /// Settings与设置窗口读写类
    /// 控件都在GroupBox内，Tag为Settings中的属性，Enable为flase时只读，
    /// TextBox、ComboBox对应string，NumercUpDown对应Int。CheckBox对应bool，DateTimePicker对应DateTime
    /// GroupBox.Tag为Enable时GroupBox.Enable对应Settings.Enable
    /// settings 文件中，StringCollection类型应设置默认值，方便类型判断
    /// </summary>
    public class NhSettings
    {
        /// <summary>
        /// 遍历窗口所有GroupBox中控件，从Settings中读出控件Tag中对应的数值。
        /// </summary>
        /// <param name="from">控件所在窗体</param>
        /// <param name="setting">Settings实例</param>
        public static void ReadSettings(Form from, System.Configuration.ApplicationSettingsBase setting)
        {
            foreach (Control gb in from.Controls)
            {
                if (gb is GroupBox)
                {
                    foreach (Control c in gb.Controls)
                    {
                        string tag = c.Tag as string;
                        if (tag == string.Empty) { continue; }

                        if (c is NumericUpDown down)
                        {
                            try
                            {
                                down.Value = Convert.ToInt32(setting[tag]);
                            }
                            catch
                            {
                                MessageBox.Show($"{setting.GetType()}[{tag}]转换Int失败。");
                            }
                        }
                        else if (c is ComboBox || c is TextBox)
                        {
                            try
                            {
                                object settingTag = setting[tag];
                                c.Text = settingTag == null ? "" : (string)settingTag;
                            }
                            catch
                            {
                                MessageBox.Show($"{setting.GetType()}[{tag}]转换String失败。");
                            }
                        }
                        else if (c is CheckBox cb)
                        {
                            try
                            {
                                cb.Checked = Convert.ToBoolean(setting[tag]);
                            }
                            catch
                            {
                                MessageBox.Show($"{setting.GetType()}[{tag}]转换Boolean失败。");
                            }
                        }
                        else if (c is DateTimePicker timePicker)
                        {
                            try
                            {
                                timePicker.Value = Convert.ToDateTime(setting[tag]);
                            }
                            catch (Exception)
                            {
                                MessageBox.Show($"{setting.GetType()}[{tag}]转换DateTime失败。");
                            }
                        }
                    }

                    if (gb.Tag as string == "Enable")
                    {
                        try
                        {
                            gb.Enabled = Convert.ToBoolean(setting["Enable"]); //有Enable者对应GroupBox.Enable
                        }
                        catch
                        {
                            MessageBox.Show($"{setting.GetType()}[{gb.Tag}]转换Boolean失败。");
                        }
                    }
                    else if (gb.Tag as string == "Enabled")
                    {
                        try
                        {
                            gb.Enabled = Convert.ToBoolean(setting["Enabled"]); //有Enable者对应GroupBox.Enable
                        }
                        catch
                        {
                            MessageBox.Show($"{setting.GetType()}[{gb.Tag}]转换Boolean失败。");
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 遍历窗口所有GroupBox中控件，数值保存到Setting文件与控件Tag中对应的属性。
        /// </summary>
        /// <param name="from">控件所在窗体</param>
        /// <param name="setting">Settings实例</param>
        public static void WriteSettings(Form from, System.Configuration.ApplicationSettingsBase setting)
        {
            foreach (Control gb in from.Controls)
            {
                if (gb is GroupBox)
                {
                    foreach (Control c in gb.Controls)
                    {
                        string tag = c.Tag as string;
                        if (tag == string.Empty || !c.Enabled) { continue; }

                        if (c is TextBox)
                        {
                            setting[tag] = c.Text;
                        }

                        if (c is NumericUpDown down)
                        {
                            setting[tag] = (int)down.Value;
                        }

                        if (c is ComboBox cbb)
                        {
                            setting[tag] = cbb.Text;
                        }

                        if (c is CheckBox cb)
                        {
                            setting[tag] = cb.Checked;
                        }
                        if (c is DateTimePicker timePicker)
                        {
                            setting[tag] = timePicker.Value;
                        }
                    }
                }
            }
            setting.Save();
        }

        /// <summary>
        /// 如控件为窗体，遍历窗口所有GroupBox中控件，从Settings中读出控件Tag中对应的数值。
        /// </summary>
        /// <param name="control">Form或GroupBox</param>
        /// <param name="setting"></param>
        /// <param name="key">setings为集合时的序号</param>
        public static void ReadSettings(Control control, System.Configuration.ApplicationSettingsBase setting, int key = 0)
        {
            if (control is Form from)
            {
                foreach (Control gb in from.Controls)
                {
                    ReadSettings(gb, setting, key);
                }
            }
            else if (control is GroupBox gb)
            {
                foreach (Control c in gb.Controls)
                {
                    string tag = c.Tag as string;

                    if (tag == string.Empty) { continue; }

                    if (c is NumericUpDown down)
                    {
                        try
                        {
                            down.Value = Convert.ToInt32(setting[tag]);
                        }
                        catch
                        {
                            MessageBox.Show($"{setting.GetType()}[{tag}]转换Int失败。");
                        }
                    }
                    else if (c is ComboBox || c is TextBox)
                    {
                        try
                        {
                            object settingTag = setting[tag];
                            if (settingTag is string s)
                            {
                                settingTag = s;
                            }
                            else if (settingTag is StringCollection sc)
                            {
                                settingTag = sc[key];
                            }

                            c.Text = settingTag == null ? "" : (string)settingTag;
                        }
                        catch
                        {
                            MessageBox.Show($"{c.Name}-{setting.GetType()}[{tag}]转换String失败。");
                        }
                    }
                    else if (c is CheckBox cb)
                    {
                        try
                        {
                            cb.Checked = Convert.ToBoolean(setting[tag]);
                        }
                        catch
                        {
                            MessageBox.Show($"{setting.GetType()}[{tag}]转换Boolean失败。");
                        }
                    }
                    else if (c is DateTimePicker timePicker)
                    {
                        try
                        {
                            timePicker.Value = Convert.ToDateTime(setting[tag]);
                        }
                        catch (Exception)
                        {
                            MessageBox.Show($"{setting.GetType()}[{tag}]转换DateTime失败。");
                        }
                    }
                }

                string gbTag = gb.Tag as string;
                if ((gbTag == "Enable") || (gbTag == "Enabled"))
                {
                    try
                    {
                        gb.Enabled = Convert.ToBoolean(setting[gbTag]); //有Enable者对应GroupBox.Enable
                    }
                    catch
                    {
                        MessageBox.Show($"{setting.GetType()}[{gb.Tag}]转换Boolean失败。");
                    }
                }
            }
        }

        /// <summary>
        /// 如是窗体遍历窗口所有GroupBox中控件，数值保存到Setting文件与控件Tag中对应的属性。
        /// </summary>
        /// <param name="control">Form or GroupBox</param>
        /// <param name="setting"></param>
        /// <param name="index">setings为集合时的序号</param>
        public static void WriteSettings(Control control, System.Configuration.ApplicationSettingsBase setting, int index = 0)
        {
            if (control is Form from)
            {
                foreach (Control gb in from.Controls)
                {
                    WriteSettings(gb, setting, index);
                }
            }
            else if (control is GroupBox gb)
            {
                foreach (Control c in gb.Controls)
                {
                    string tag = c.Tag as string;
                    if (tag == string.Empty || !c.Enabled) { continue; }

                    if (c is TextBox)
                    {
                        if (setting[tag] is string)
                        {
                            setting[tag] = c.Text;
                        }
                        else if (setting[tag] is StringCollection sc)
                        {
                            if (index == sc.Count)
                            {   //新序号 增加
                                sc.Add(c.Text);
                            }
                            else
                            {   //有修改
                                sc[index] = c.Text;
                            }
                        }
                    }
                    else if (c is NumericUpDown down)
                    {
                        setting[tag] = (int)down.Value;
                    }
                    else if (c is ComboBox cbb)
                    {
                        setting[tag] = cbb.Text;
                    }
                    else if (c is CheckBox cb)
                    {
                        setting[tag] = cb.Checked;
                    }
                    else if (c is DateTimePicker timePicker)
                    {
                        setting[tag] = timePicker.Value;
                    }
                }
            }

            setting.Save();
        }
    }
}
